package org.geektimes.rest.client;

import javax.ws.rs.HttpMethod;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.InvocationCallback;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Future;

/**
 * @author lanxing
 * @date 2021/3/29 18:17
 */
public class HttpPostInvocation extends AbstractHttpMethodInvocation implements Invocation {

    private Entity entity;

    private final URI uri;

    private final URL url;

    private final MultivaluedMap<String, Object> headers;

    HttpPostInvocation(URI uri, MultivaluedMap<String, Object> headers,Entity entity) {
        this.uri = uri;
        this.headers = headers;
        this.entity = entity;
        try {
            this.url = uri.toURL();
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException();
        }
    }


    @Override
    public Invocation property(String name, Object value) {
        return this;
    }

    @Override
    public Response invoke() {
        HttpURLConnection connection = null;
        MediaType mediaType = entity.getVariant().getMediaType();
        //当请求为JSON时
        if(MediaType.APPLICATION_JSON_TYPE.equals(mediaType)){
            try {
                String requestBody = entity.getEntity().toString();
                connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod(HttpMethod.POST);
                connection.setDoOutput(true);
                //设置头信息
                headers.add("Content-Type",MediaType.APPLICATION_JSON);
                setRequestHeaders(connection,headers);
                //发起POST请求
                OutputStream os = connection.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8);
                osw.write(requestBody);
                osw.flush();
                osw.close();
                os.close();
                connection.connect();
                //构建返回结果
                return buildResponse(connection);
            } catch (Exception e) {
                throw new RuntimeException("请求失败"+e);
            }
        }
        return null;
    }


    @Override
    public <T> T invoke(Class<T> responseType) {
        Response response = invoke();
        return response.readEntity(responseType);
    }

    @Override
    public <T> T invoke(GenericType<T> responseType) {
        Response response = invoke();
        return response.readEntity(responseType);
    }

    @Override
    public Future<Response> submit() {
        return null;
    }

    @Override
    public <T> Future<T> submit(Class<T> responseType) {
        return null;
    }

    @Override
    public <T> Future<T> submit(GenericType<T> responseType) {
        return null;
    }

    @Override
    public <T> Future<T> submit(InvocationCallback<T> callback) {
        return null;
    }
}
